<template>
  <KView class="sys-input-number" @click="inputClick">
    <template v-if="hasInput">
      <KView class="sys-input-number-decrease" @click="decreaseValue">
        <KView class="sys-input-number-horizontal"></KView>
      </KView>
      <KView class="sys-input-number-value">
        <input v-model="showValue" :disabled="disabled" @change="valueChange">
      </KView>
    </template>
    <KView v-else class="sys-input-number-noneInput" @click.stop></KView>
    <KView class="sys-input-number-increase" @click="increaseValue">
      <KView class="sys-input-number-horizontal"></KView>
      <KView class="sys-input-number-vertical"></KView>
    </KView>
  </KView>
</template>

<script>
  import GlobalData from 'utils/globalData';
  import SystemUtil from 'utils/systemUtil';

  export default {
    props: {
      value: {
        type: Number,
        required: true
      },
      min: Number,
      max: Number,
      step: {
        type: Number,
        default: 1
      },
      precision: Number,
      disabled: {
        type: Boolean,
        default: false
      },
      mode: {
        type: String,
        default: 'normal'
      }
    },

    watch: {
      value() {
        if (this.inputValue !== null) {
          this.inputValue = null;
          return;
        }
        this.showValue = this.value ? this.value : '';
      }
    },

    computed: {
      hasInput() {
        let mode = this.mode;
        if (mode === 'normal') {
          return true;
        }

        let value = this.value;
        if (SystemUtil.isEmpty(value)) {
          return false;
        }

        let min = this.min;
        if (min === undefined) {
          return true;
        }
        return value >= min;
      }
    },

    data() {
      return {
        plusImg: GlobalData.images.plus,
        showValue: this.value ? this.value : '',
        inputValue: null
      };
    },

    methods: {
      valueChange() {
        let newValue = this.getNewValue(this.showValue);
        if (newValue === undefined) {
          this.showValue = this.value;
          return;
        }

        let min = this.min;
        if (min !== undefined && newValue < min) {
          newValue = min;
        }

        let max = this.max;
        if (max !== undefined && newValue > max) {
          newValue = max;
        }

        if (newValue === this.value) {
          this.showValue = newValue;
          return;
        }
        this.toChangeValue(value);
      },

      toChangeValue(value) {
        this.inputValue = value;
        this.showValue = value;
        this.$emit('input', value);
        this.$emit('change', value);
      },

      getNewValue(value) {
        if (typeof value === 'string') {
          let reg = /^-?([1-9]\d*\.[0-9]\d*|0\.[0-9]\d*|0)$/;
          if (!reg.test(value)) {
            return undefined;
          }
          value = Number(value);
        }

        let precision = this.precision;
        if (precision !== undefined) {
          value = SystemUtil.roundValue(value, precision);
        }

        return value;
      },

      decreaseValue() {
        if (this.disabled) {
          return;
        }

        let newValue = this.getNewValue(this.showValue);
        let step = this.step;
        newValue -= step;
        let min = this.min;
        if (min !== undefined) {
          if (newValue < min) {
            return;
          }
        }
        this.toChangeValue(newValue);
      },

      increaseValue() {
        if (this.disabled) {
          return;
        }

        let newValue = this.getNewValue(this.showValue);
        let step = this.step;
        newValue += step;
        let max = this.max;
        if (max !== undefined) {
          if (newValue > max) {
            return;
          }
        }
        this.toChangeValue(newValue);
      },

      inputClick() {
        this.$emit('click');
      }
    }
  };

</script>

<style lang="scss">
  .sys-input-number {
    width: 100%;
    height: formatPx(40);
    display: flex;

    .sys-input-number-decrease,
    .sys-input-number-increase {
      height: calc(100% - 2px);
      width: calc(#{formatPx(40)} - 2px);
      border-radius: formatPx(20);
      position: relative;
    }

    .sys-input-number-horizontal {
      position: absolute;
      top: calc(50% - 1px);
      bottom: calc(50% - 1px);
      left: formatPx(8);
      right: formatPx(8);
      border-radius: 2px;
    }

    .sys-input-number-vertical {
      position: absolute;
      left: calc(50% - 1px);
      right: calc(50% - 1px);
      top: formatPx(8);
      bottom: formatPx(8);
      border-radius: 2px;
    }

    .sys-input-number-decrease {
      color: #59c264;
      background: #ffffff;
      border: 1px solid #59c264;

      >div {
        background: #59c264;
      }
    }

    .sys-input-number-increase {
      background: #59c264;
      border: 1px solid #59c264;

      >div {
        background: #ffffff;
      }
    }

    .sys-input-number-value {
      flex: 1;
      padding: 0 formatPx(5);

      >input {
        height: 100%;
        width: 100%;
        border: none;
        font-size: inherit;
        text-align: center;
        line-height: formatPx(40);
      }
    }
    .sys-input-number-noneInput{
      flex: 1;
    }
  }

</style>
